package inference;

import java.util.ArrayList;
import java.util.Iterator;

import model.ModelParameters;
import model.PredicateInfo;

import com.analog.lyric.dimple.model.Discrete;

import utils.IntPair;
import utils.Pair;

public class ColumnTypeFactor {
	public static Pair<int[][], double[]> createFactor(Discrete predicate_variable, Discrete column_type_variable,
			   ModelParameters params) {
		Object[] predicates = predicate_variable.getDomain().getElements();
		int unk_pred_id = predicates.length - 1;
		Object[] column_types = column_type_variable.getDomain().getElements();
		int unk_type_id = column_types.length - 1;
		
		// Set up output data structures.
		int init_size = predicates.length;
		ArrayList<IntPair> indices = new ArrayList<IntPair>(init_size);
		ArrayList<Double> probabilities = new ArrayList<Double>(init_size);
	
		indices.add(new IntPair(unk_pred_id, unk_type_id));
		probabilities.add(1.0);
		
		for (int pred = 0; pred < predicates.length; pred++) {
			if (pred == unk_pred_id) {
				continue;
			}
			Integer predicate_id = (Integer)(predicates[pred]);
			PredicateInfo pred_info = params.getTableInformation().getPredicateInfo(predicate_id);
			int type_idx = indexOfInteger(column_types, pred_info.getRangeId());
			indices.add(new IntPair(pred, type_idx));
			probabilities.add(1.0);
//			for (int type = 0; type < column_types.length; type++) {
//				if (type == type_idx) {
//					continue;
//				}
//				indices.add(new IntPair(pred, type));
//				probabilities.add((0.0001 / (column_types.length - 1)));
//			}
		}
		
		return translateListsToPrimitives(indices, probabilities);
	}
	
	private static int indexOfInteger(Object[] integers, Integer integer) {
		for (int i = 0; i < integers.length; i++) {
			if (((Integer)(integers[i])).intValue() == integer.intValue()) return i;
		}
		return -1;
	}
	
	private static Pair<int[][], double[]> translateListsToPrimitives(ArrayList<IntPair> indices, ArrayList<Double> probabilities) {
		int[][] indices_arr = new int[indices.size()][2];
		double[] prob_arr = new double[probabilities.size()];
		
		Iterator<IntPair> it = indices.iterator();
		Iterator<Double> it_prob = probabilities.iterator();
		for (int i = 0; i < indices.size(); i++) {
			IntPair pair = it.next();
			indices_arr[i] = pair.toArray();
			prob_arr[i] = it_prob.next().doubleValue();
		}
		
		return new Pair<int[][], double[]>(indices_arr, prob_arr);
	}
}
